// import './leaflet-wmts.js'
const GeowayMap = function () {
  /**
   * 地图对象
   */
  this.geowayMap = null;

  /**
   *获取地图对象
   **/
  this.getMap = () => this.geowayMap;

  /**
   *编辑图层
   **/
  this.editLayer = null;
  this.mapSplitControl = null;
  this.matrixIds = [];
  for (let i = 0; i < 21; ++i) {
    this.matrixIds[i] = {
      identifier: "" + (i),
      topLeftCorner: new L.LatLng(90, -180),
    };
  }

  /**
   *获取编辑图层
   */
  this.getEditLayer = () => this.editLayer;
  /**
   * 初始化地图
   */
  this.initMap = (mapdiv, cfg) => {
    this.geowayMap = L.map(mapdiv, {
      crs: cfg.mapInfo.crs,
      zoomControl: false,
      center: cfg.mapInfo.center,
      zoom: cfg.mapInfo.level,
      minZoom: cfg.mapInfo.minlevel,
      maxZoom: cfg.mapInfo.maxlevel,
      /*fullscreenControl: true,
      fullscreenControlOptions: { // optional
        title:"全屏",
        position: 'topright'
      }*/
      //maxBounds:cfg.mapInfo.maxBounds
    });
    this.initManagerLayer();
    // this.initBaseControls();
  };
  /**
   *添加辅助图层管理
   */
  this.initManagerLayer = () => {
    //编辑图层
    this.editLayer = L.featureGroup();
    this.geowayMap.addLayer(this.editLayer);
  };
  /**
   *初始化地图控件
   *map 地图对象
   *config 控件显示配置
   **/
  this.initBaseControls = config => {
    if (typeof (config) == "undefined") config = {};
    //加载比例尺
    if (!config.hasOwnProperty('IsScale') || config.IsScale == true) {
      L.control.scale().addTo(this.geowayMap);
      L.control.zoom({
        zoomInTitle: '放大',
        zoomOutTitle: '缩小',
        position: 'topright'
      }).addTo(this.geowayMap);
      L.control.mousePosition().addTo(this.geowayMap);
    }
  };
  /**
   *初始化图层
   *@param layers添加图层数组
   *@param config图层配置信息
   */
  this.addMapLayers = (layers, config) => {
    if (typeof (config) == "undefined") layers = [];
    for (let count = 0; count < layers.length; count++) {
      let layerinfo = layers[count];
      if (layerinfo.serviceType === "wmts") {
        this.addMapLayer(layerinfo);
      } else {
        L.tileLayer(layerinfo.url, {
          tileSize: 256,
          zoomOffset: 1,
          subdomains: layerinfo.subdomains,
          attribution: layerinfo.attribution
        }).addTo(this.geowayMap);
      }
    }
  };
  /**
   * 添加图层信息
   * @param layerinfo图层信息
   */
  this.addMapLayer = layerinfo => {
    let layer = null;
    let visibility = typeof (layerinfo.visibility) == "undefined" ? true : layerinfo.visibility;
    let isBaseLayer = typeof (layerinfo.isBaseLayer) == "undefined" ? false : layerinfo.isBaseLayer;
    switch (layerinfo.serviceType) {
      case "wmts":
        let style = "default";
        let format = typeof (layerinfo.format) == "undefined" ? "image/png" : layerinfo.format;
        let layerleName;
        let tilematrixSet = typeof (layerinfo.tilematrixSet) == "undefined" ? "" : layerinfo.tilematrixSet;
        const matrixIds = [];
        for (let i = 0; i < 23; ++i) {
          matrixIds[i] = {
            identifier: "" + (i + 1),
            topLeftCorner: new L.LatLng(layerinfo.orgin[0], layerinfo.orgin[1])
          };
        }
        layer = new L.TileLayer.WMTS(layerinfo.url, {
          layer: layerinfo.layer,
          style: "",
          tilematrixSet: tilematrixSet,
          format: format,
          matrixIds: matrixIds,
          attribution: layerinfo.attribution
        });
        break;
    }
    this.geowayMap.addLayer(layer);
  };

  /**
   *移除图层
   *@param layerId 图层id(注：如果为空则移除所有图层)
   */
  this.removeLayer = layerId => {
    var that = this;
    try {
      if (layerId == null || layerId == 'undefined') {
        this.geowayMap.eachLayer(function (layer) {
          if (layer.options) {
            if (layer.options.attribution == "worldVector" || layer.options.attribution == "worldVectorLocal" || layer.options.attribution == "worldImage" || layer.options.attribution == "worldImageLocal") {
              that.geowayMap.removeLayer(layer);
            }
          }
        });
      } else {
        this.geowayMap.eachLayer(function (layer) {
          if (layer._leaflet_id == layerId) {
            that.geowayMap.removeLayer(layer);
          }
        });
      }
    } catch (error) {
      console.log("移除图层失败：" + error);
    }
  };
  this.PolyView = function (coordinates, style, isView, type, pane) {
    if (type == undefined || type == null) {
      type = "Polygon";
    }
    if (pane === null || pane === "" || pane == undefined) {
      pane = "overlayPane";
    }
    let geoJsonLayer = L.geoJson(coordinates, {
      style: style,
      pane: pane
    }).addTo(this.editLayer);

    if (isView) {
      let latling = geoJsonLayer.getBounds().getCenter();
      let center = L.latLng(latling.lat, latling.lng);
      let currentZoom = this.geowayMap().getBoundsZoom(geoJsonLayer.getBounds()); // 缩放比例
      this.geowayMap().setView(center, currentZoom);
    }
    return geoJsonLayer;
  };
  /**
   * 清除地图上所有图层
   */
  this.removeDrawLayer = () => {
    this.editLayer.clearLayers();
  }
  /**
   * 全幅
   */
  this.fullMap = () => {
    this.geowayMap.setView([37, 102], 3);
  }

  /**
   * 放大按钮
   */
  this.zoomOut = () => {
    let tmprec;
    let rectangle;
    let latlngs = [];
    this.geowayMap.dragging.disable();
    this.geowayMap.on('mousedown', (e) => {
      if (typeof tmprec != 'undefined') {
        tmprec.remove();
      }
      //左上角坐标
      latlngs[0] = e.latlng;
      //开始绘制，监听鼠标移动事件
      this.geowayMap.on('mousemove', (e) => {
        this.editLayer.clearLayers();
        latlngs[1] = e.latlng;
        //删除临时矩形
        if (typeof tmprect != 'undefined') {
          tmprec.remove();
        }
        //添加临时矩形
        tmprec = L.rectangle(latlngs, this.drawStyleMap.Polygon).addTo(this.editLayer);
      })
    }); //点击地图
    this.geowayMap.on('mouseup', (e) => {
      this.editLayer.clearLayers();
      //矩形绘制完成，移除临时矩形，并停止监听鼠标移动事件
      this.geowayMap.off('mousedown');
      this.geowayMap.off('mousemove');
      this.geowayMap.off('mouseup');
      //右下角坐标
      latlngs[1] = e.latlng;
      let bound = [
        [latlngs[0].lat, latlngs[0].lng],
        [latlngs[1].lat, latlngs[1].lng]
      ];
      this.geowayMap.fitBounds(bound);
      this.geowayMap.dragging.enable();
    });
  };

  /**
   * 缩小按钮
   */
  this.zoomIn = () => {
    let tmprec;
    let rectangle;
    let latlngs = [];
    this.geowayMap.dragging.disable();
    this.geowayMap.on('mousedown', (e) => {
      if (typeof tmprec != 'undefined') {
        tmprec.remove();
      }
      //左上角坐标
      latlngs[0] = e.latlng;
      //开始绘制，监听鼠标移动事件
      this.geowayMap.on('mousemove', (e) => {
        this.editLayer.clearLayers();
        latlngs[1] = e.latlng;
        //删除临时矩形
        if (typeof tmprect != 'undefined') {
          tmprec.remove();
        }
        //添加临时矩形
        tmprec = L.rectangle(latlngs, this.drawStyleMap.Polygon).addTo(this.editLayer);
      })
    }); //点击地图
    this.geowayMap.on('mouseup', (e) => {
      this.editLayer.clearLayers();
      //矩形绘制完成，移除临时矩形，并停止监听鼠标移动事件
      this.geowayMap.off('mousedown');
      this.geowayMap.off('mousemove');
      this.geowayMap.off('mouseup');
      //右下角坐标
      latlngs[1] = e.latlng;
      let oBound = [
        [latlngs[0].lat, latlngs[0].lng],
        [latlngs[1].lat, latlngs[1].lng]
      ];
      let _oBound, _bounds, nDx, nDy, nDx1, nDy1, oBoxCenter,
        nNewX0, nNewX1, nNewY0, nNewY1, oNewBound;
      _oBound = new L.Bounds(oBound[0], oBound[1]);
      _bounds = this.geowayMap.getBounds();
      nDx = _bounds._southWest.lat - _bounds._northEast.lat;
      nDy = _bounds._southWest.lng - _bounds._northEast.lng;
      nDx1 = oBound[1][0] - oBound[0][0];
      nDy1 = oBound[1][1] - oBound[0][1];
      oBoxCenter = _oBound.getCenter();
      nNewX0 = oBoxCenter.x - nDx / nDx1 * nDx / 2;
      nNewX1 = oBoxCenter.x + nDx / nDx1 * nDx / 2;
      nNewY0 = oBoxCenter.y - nDy / nDy1 * nDy / 2;
      nNewY1 = oBoxCenter.y + nDy / nDy1 * nDy / 2;
      oNewBound = [
        [nNewX0, nNewY0],
        [nNewX1, nNewY1]
      ];
      this.geowayMap.fitBounds(oNewBound);
      this.geowayMap.dragging.enable();
    });
  };
  /**
   * 绘制矩形
   */
  this.drawRectangle = () => {
    this.editLayer.clearLayers();
    let rectangle;
    let tmprec;
    let latlngs = [];
    this.geowayMap.dragging.disable();
    this.geowayMap.on('mousedown', (e) => {
      if (typeof tmprec != 'undefined') {
        tmprec.remove()
      }
      //左上角坐标
      latlngs[0] = e.latlng;
      //开始绘制，监听鼠标移动事件
      this.geowayMap.on('mousemove', (e) => {
        this.editLayer.clearLayers();
        latlngs[1] = e.latlng;
        //删除临时矩形
        if (typeof tmprect != 'undefined') {
          tmprec.remove()
        }
        //添加临时矩形
        tmprec = L.rectangle(latlngs, this.drawStyleMap.Polygon).addTo(this.editLayer);
      })
    });
    this.geowayMap.on('mouseup', (e) => {
      this.editLayer.clearLayers();
      //矩形绘制完成，移除临时矩形，并停止监听鼠标移动事件
      this.geowayMap.off('mousedown');
      this.geowayMap.off('mousemove');
      this.geowayMap.off('mouseup');
      //右下角坐标
      latlngs[1] = e.latlng;
      rectangle = L.rectangle(latlngs, this.drawStyleMap.Polygon);
      let result = [];
      result.push(latlngs);
      rectangle.addTo(this.editLayer);
      this.geowayMap.dragging.enable();
    });
  }

  /**
   * 绘制线
   */
  this.drawPolyline = () => {
    this.editLayer.clearLayers();
    let rectangle;
    let tmprec;
    let latlngs = [];
    this.geowayMap.dragging.disable();
    this.geowayMap.on('mousedown', (e) => {
      if (typeof tmprec != 'undefined') {
        tmprec.remove()
      }
      //左上角坐标
      latlngs[0] = e.latlng;
      //开始绘制，监听鼠标移动事件
      this.geowayMap.on('mousemove', (e) => {
        this.editLayer.clearLayers();
        latlngs[1] = e.latlng;
        //删除临时矩形
        if (typeof tmprect != 'undefined') {
          tmprec.remove()
        }
        //添加临时矩形
        tmprec = L.polyline(latlngs, this.drawStyleMap.Line).addTo(this.editLayer);
      })
    });
    this.geowayMap.on('mouseup', (e) => {
      this.editLayer.clearLayers();
      //矩形绘制完成，移除临时矩形，并停止监听鼠标移动事件
      this.geowayMap.off('mousedown');
      this.geowayMap.off('mousemove');
      this.geowayMap.off('mouseup');
      //右下角坐标
      latlngs[1] = e.latlng;
      rectangle = L.polyline(latlngs, this.drawStyleMap.Line);
      let result = [];
      result.push(latlngs);
      rectangle.addTo(this.editLayer);
      this.geowayMap.dragging.enable();
    });
  }
  /**
   * 绘制点
   */
  this.drawPoint = () => {
    this.editLayer.clearLayers();
    let rectangle;
    let tmprec;
    let latlngs = [];
    this.geowayMap.dragging.disable();
    this.geowayMap.on('mousedown', (e) => {
      if (typeof tmprec != 'undefined') {
        tmprec.remove()
      }
      //左上角坐标
      latlngs[0] = e.latlng.lat;
      latlngs[1] = e.latlng.lng;
      //开始绘制，监听鼠标移动事件
      this.geowayMap.on('mousemove', (e) => {
        this.editLayer.clearLayers();
        //删除临时矩形
        if (typeof tmprect != 'undefined') {
          tmprec.remove()
        }
        //添加临时矩形
        tmprec = L.circle(latlngs, {
          radius: 1
        }, this.drawStyleMap.Line).addTo(this.editLayer);
      })
    });
    this.geowayMap.on('mouseup', (e) => {
      this.editLayer.clearLayers();
      //矩形绘制完成，移除临时矩形，并停止监听鼠标移动事件
      this.geowayMap.off('mousedown');
      this.geowayMap.off('mousemove');
      this.geowayMap.off('mouseup');
      rectangle = L.circle(latlngs, {
        radius: 1
      }, this.drawStyleMap.Line);
      let result = [];
      result.push(latlngs);
      rectangle.addTo(this.editLayer);
      this.geowayMap.dragging.enable();
    });
  }

  /**
   *全局绘制样式配置
   **/
  this.drawStyleMap = {
    "Point": {
      pointRadius: 5,
      graphicName: "circle",
      fillColor: "white",
      fillOpacity: 1,
      strokeWidth: 1,
      strokeOpacity: 1,
      strokeColor: "#ed7540",
      strokeLinecap: "round"
    },
    "Line": {
      strokeWidth: 3,
      strokeOpacity: 1,
      strokeColor: "#ed7540",
      strokeDashstyle: "longdash",
      strokeLinecap: "butt"
    },
    "Polygon": {
      color: '#3388FF',
      fillOpacity: 0.1,
      weight: 2
    }
  };
  /**
   * 高亮选中图形
   */
  this.initHightPoly = function (geometry) {
    var states = [geometry];
    var geoJsonLayer = L.geoJson(geometry, {
      style: this.drawStyleMap.Polygon
    }).addTo(this.editLayer);
    return geoJsonLayer;
  }

  this.addAPolygon = function (geometry) {
    this.editLayer.clearLayers();
    let polygon = geometry.coordinates;
    let cp = geometry.cp;
    let center = L.latLng(cp[1], cp[0]);
    let polygon1 = [];
    for (let item in polygon) {
      let cor = polygon[item];
      let cor1 = [];
      cor1[0] = cor[1];
      cor1[1] = cor[0];
      polygon1.push(cor1);
    }
    let polygon2 = L.polygon(polygon1, {
      color: 'red',
      fillColor: '#f03',
      fillOpacity: 0.2
    });
    polygon2.addTo(this.editLayer);
    this.geowayMap.setView(center, 5);
  }
  this.addOnePolygon = function (geometry, scale) {
    let finalscale = scale || 10;
    this.editLayer.clearLayers();
    let polygon = geometry.coordinates;
    let cp = geometry.cp;
    let center = L.latLng(cp[1], cp[0]);
    let polygon1 = [];
    for (let item in polygon) {
      let cor = polygon[item];
      let cor1 = [];
      cor1[0] = cor[1];
      cor1[1] = cor[0];
      polygon1.push(cor1);
    }
    let polygon2 = L.polygon(polygon1, {
      color: '#1E90FF',
      fillColor: '#87CEEB',
      fillOpacity: 0.7
    });
    polygon2.addTo(this.editLayer);
    this.geowayMap.setView(center, finalscale);
  }
  this.addMuchPolygon = function (arr, scale,pointArr) {
    this.editLayer.clearLayers();
    let finalscale = scale || 10;
    let center;
    let geoJsonLayerArr = []
    for (let i = 0; i < arr.length; i++) {
      let geometry = arr[i];
      let polygon = geometry.coordinates;
      let cp = geometry.cp;
      center = L.latLng(cp[1], cp[0]);
      let polygon1 = [];
      for (let item in polygon) {
        let cor = polygon[item];
        let cor1 = [];
        cor1[0] = cor[1];
        cor1[1] = cor[0];
        polygon1.push(cor1);
      }
      let polygon2 = L.polygon(polygon1, {
        color: '#1E90FF',
        fillColor: '#87CEEB',
        fillOpacity: 0,
      });
      geoJsonLayerArr.push(polygon2)
      polygon2.addTo(this.editLayer);
    }
    let layerGroup = L.geoJSON();
    geoJsonLayerArr.forEach(geojsonLayer => {
      layerGroup.addLayer(geojsonLayer)
    })
    this.geowayMap.setView(center, finalscale);
    return layerGroup
  }
  this.addArrPolygon = function (arr) {
    let center;
    this.editLayer.clearLayers();
    for (let i = 0; i < arr.length; i++) {
      let geometry = arr[i];
      let polygon = geometry.coordinates;
      let cp = geometry.cp;
      center = L.latLng(cp[1], cp[0]);
      let polygon1 = [];
      for (let item in polygon) {
        let cor = polygon[item];
        let cor1 = [];
        cor1[0] = cor[1];
        cor1[1] = cor[0];
        polygon1.push(cor1);
      }
      let polygon2 = L.polygon(polygon1, {
        color: 'red',
        fillColor: '#f03',
        fillOpacity: 0.2
      });
      polygon2.addTo(this.editLayer);
    }
    this.geowayMap.setView(center, 4);
  }

  this.addMultiPolygon = function (geometry) {
    this.editLayer.clearLayers();
    var polygons = geometry.coordinates;
    var cp = [];
    for (let item1 in polygons) {
      //取出多边形
      let polygon = polygons[item1];
      for (let item2 in polygon) {
        //取出坐标序列
        let coords = polygon[item2];
        var polygon1 = [];
        for (let item3 in coords) {
          let coord = coords[item3];
          let cor1 = [];
          cor1[0] = cor[1];
          cor1[1] = cor[0];
          polygon1.push(cor1);
          cp[0] += cor1[0];
          cp[1] += cor1[1]
        }
        var polygon2 = L.polygon(polygon1, {
          color: 'red',
          fillColor: '#f03',
          fillOpacity: 0.2
        });
        cp[0] /= coords.length;
        cp[1] /= coords.length;
        polygon2.addTo(this.editLayer);
        this.geowayMap.setView(cp, 5);
      }
    }


  },

    this.renderHeatMap = function (heat) {
      this.editLayer.clearLayers();
      let cfg = {
        // radius should be small ONLY if scaleRadius is true (or small radius is intended)
        // if scaleRadius is false it will be the constant radius used in pixels
        "radius": 10,
        "maxOpacity": .8,
        // scales the radius based on map zoom
        "scaleRadius": true,
        // if set to false the heatmap uses the global maximum for colorization
        // if activated: uses the data maximum within the current map boundaries
        //   (there will always be a red spot with useLocalExtremas true)
        "useLocalExtrema": true,
        latField: 'lat',
        // which field name in your data represents the longitude - default "lng"
        lngField: 'lng',
        // which field name in your data represents the data value - default "value"
        valueField: 'val'
      };
      L.heatLayer(heat, cfg).addTo(this.editLayer);
    },
    this.sideBySide = function (imageOption) {
      // this.editLayer.clearLayers();
      if (this.mapSplitControl) {
        this.mapSplitControl.remove();
        this.mapSplitControl = null;
      } else {
        let this_ = this;
        let osmLayer = imageOption.skyMap1.addTo(this_.geowayMap);
        let stamenLayer = imageOption.skyMap2.addTo(this_.geowayMap);
        this_.mapSplitControl = L.control.sideBySide(osmLayer, stamenLayer);
        this_.mapSplitControl.addTo(this_.geowayMap);
      }
    }
}
export default GeowayMap
